import { AssignTask, IAssignTask } from '@/ts/core/work/assign';
import React, { createContext, useEffect, useMemo, useState } from 'react';
import { Button, Empty, message, Result } from 'antd';
import cls from './index.module.less';
import { useEffectOnce } from 'react-use';
import { AssignTree } from './assignTree';
import { XAssignTask } from '@/ts/base/schema';
import { IAssignTaskTree } from '@/ts/core/work/assignTree';
import { getEmptySummary } from '@/ts/core/work/assign/assignTask/status';
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
import { AssignStatusType, NodeType } from '@/ts/base/enum';
import { AssignDataView } from '@/components/DataPreview/assign/assignDataView';
import AssignStart from '@/components/DataPreview/assign/assignStart';
import { AssignView } from '@/components/DataPreview/assign/assignView';
import orgCtrl from '@/ts/controller';
import EntityIcon from '@/components/Common/GlobalComps/entityIcon';
import { delay } from '@/ts/base/common/timer';
import ApprovalHistory from './approvalHistory';
import { command } from '@/ts/base';

export interface IProps {
  assignTask: IAssignTask;
  onTreeSelected?: (entity: IAssignTask) => void;
}
export const AssignTaskContext = createContext(null as IAssignTask | null);

const Assign: React.FC<IProps> = (props) => {
  const [tree, setTree] = useState<XAssignTask[]>([]);
  const [expand, setExpand] = useState<boolean>(true);
  const [showType, setShowType] = useState<string>('workdetails');
  const [treeNodes, setTreeNodes] = useState<XAssignTask[]>([]);
  const [assignTree, setAssignTree] = useState<IAssignTaskTree | undefined>(undefined);
  const [currentTask, setCurrentTask] = useState<IAssignTask | undefined>(
    props.assignTask,
  );
  useEffect(() => {
    const id = props.assignTask?.subscribe((_, cmd, typeName, showText) => {
      if (cmd === 'actionChange' && typeName === '任务' && showText) {
        setShowType(showText);
      }
    });
    return () => props.assignTask?.unsubscribe(id);
  }, []);
  function buildTree(data: XAssignTask[]) {
    const map: any = {};
    if (!data.find((value) => value.id === props.assignTask.id)) {
      data.push(props.assignTask.metadata);
    }
    data.forEach((item) => {
      map[item.id] = { ...item, children: [] };
    });

    const tree: XAssignTask[] = [];
    data.forEach((item) => {
      if (item.parentId && map[item.parentId]) {
        const parent = map[item.parentId];
        if (parent) {
          parent.children.push(map[item.id]);
        }
      } else {
        tree.push(map[item.id]);
      }
    });
    return tree;
  }

  async function loadTree() {
    const assignTree = await props.assignTask.loadTree();
    setAssignTree(assignTree);
    if (!assignTree) {
      message.error('找不到当前任务树');
    }
    const loadNodes: XAssignTask[] | undefined = await assignTree?.loadSubNodes(
      props.assignTask.id,
      true,
    );
    if (!loadNodes) {
      return;
    }
    const treeNodes = loadNodes.filter((value) => value.id !== props.assignTask.id);
    treeNodes.push(props.assignTask.metadata);
    const builtTree = buildTree(loadNodes ?? []);
    setTreeNodes(treeNodes ?? []);
    setTree(builtTree);
  }

  const showTree = useMemo(() => {
    if (tree.length == 0) {
      return false;
    }
    return tree[0].children!.length > 0;
  }, [tree]);

  const treeSummary = useMemo(() => {
    let summary = getEmptySummary();
    treeNodes.forEach((node) => {
      if (node.taskStatus) {
        switch (node.taskStatus) {
          case 'received':
            summary.received++;
            break;
          case 'submitted':
            summary.submitted++;
            break;
          case 'finished':
            summary.finished++;
            break;
          case 'rejected':
            summary.submitted++;
            break;
          case 'changed':
            summary.submitted++;
            break;
          case 'assigned':
            summary.received++;
            break;
          default:
            summary.empty++;
            break;
        }
      } else {
        summary.empty++;
      }
      summary.total++;
    });
    return summary;
  }, [treeNodes]);

  useEffectOnce(() => {
    if (props.assignTask.metadata.nodeType === NodeType.Summary) {
      loadTree();
    }
  });
  async function handleNodeSelect(_node: XAssignTask) {
    setCurrentTask(undefined);
    await delay(10);
    const NewAssignTask = new AssignTask(
      _node,
      assignTree ? assignTree.directory.target : props.assignTask.target,
    );
    props?.onTreeSelected?.(NewAssignTask);
    setCurrentTask(NewAssignTask);
  }
  const renderContent = React.useMemo(() => {
    if (!currentTask) {
      return <Empty />;
    }

    const { metadata } = currentTask;
    const { assignContent, thingId, taskStatus, instanceId, receiveUserId, isAutoFill } =
      metadata;
    if (showType === 'flowdetails') {
      return <ApprovalHistory current={currentTask} />;
    }
    // 任务填报时间限制
    const curDate = new Date();
    const startDate = assignContent?.startDate ? new Date(assignContent.startDate) : null;
    const endDate = assignContent?.endDate ? new Date(assignContent.endDate) : null;
    if (startDate && endDate && (curDate < startDate || curDate > endDate)) {
      return <AssignDataView assignTask={currentTask} />;
    }
    // 自动补全的任务
    if (thingId && isAutoFill) {
      return <AssignDataView assignTask={currentTask} />;
    }
    // 完成的任务
    if (thingId && taskStatus === AssignStatusType.FINISHED) {
      return <AssignView assignTask={currentTask} />;
    }
    // 有实例ID且任务状态不为 "RECEIVED", "ASSIGNED", "REJECTED"
    const invalidTaskStatus = [
      AssignStatusType.RECEIVED,
      AssignStatusType.ASSIGNED,
      AssignStatusType.REJECTED,
    ];
    if (instanceId && !invalidTaskStatus.includes(taskStatus)) {
      return <AssignView assignTask={currentTask} />;
    }
    // 当前任务等待他人办理
    const find = orgCtrl.user.companys.find(
      (c) => c.id === currentTask.metadata.belongId || c.id === currentTask.belongId,
    );
    if (receiveUserId !== orgCtrl.user.id && !find?.hasSuperAuth()) {
      return (
        <Empty>
          当前任务正在等待
          <EntityIcon entityId={receiveUserId} showName />
          办理
        </Empty>
      );
    }
    // 默认返回任务开始界面
    return (
      <AssignStart
        assignTask={currentTask}
        finished={() =>
          handleNodeSelect(currentTask?.metadata || props.assignTask.metadata)
        }
      />
    );
  }, [currentTask, showType]);

  return (
    <div className={cls['assign']}>
      <div className={cls['content']}>
        {showTree ? (
          <div className={[cls['left-content'], !expand ? 'is-collapsed' : ''].join(' ')}>
            <Button
              type="primary"
              shape="round"
              className={cls['expand-btn']}
              onClick={() => {
                setExpand(!expand);
              }}>
              {expand ? <MenuFoldOutlined color="#154AD8" /> : <MenuUnfoldOutlined />}
            </Button>
            <AssignTree
              assignTask={props.assignTask}
              assignTree={assignTree}
              width={300}
              tree={treeNodes}
              onNodeSelect={handleNodeSelect}
              readOnly={true}
              summary={treeSummary}
              exportData={tree}
            />
          </div>
        ) : (
          <></>
        )}
        <div className={cls['assign-wrap']}>{renderContent}</div>
      </div>
    </div>
  );
};

export default Assign;

export const EmptyAssign = (props: IProps) => {
  const [loading, setLoading] = useState(false);

  return (
    <div className={cls['assign']}>
      <div className={cls['content']}>
        <div className={cls['empty-assign']}>
          <Result status="info" title="任务未接收">
            <Button
              type="primary"
              loading={loading}
              onClick={async () => {
                try {
                  setLoading(true);
                  const ret = await props.assignTask.receiveAssignTask();
                  if (!ret) {
                    return;
                  }
                  command.emitter('assign', 'refresh');
                  message.success('接收任务成功');
                } finally {
                  setLoading(false);
                }
              }}>
              接收任务
            </Button>
          </Result>
        </div>
      </div>
    </div>
  );
};
